#include "netlib/net/event/event_loop_threadpool.h"

#include <utility>

#include "netlib/net/event/event_loop.h"
#include "netlib/net/event/event_loop_thread.h"

netlib::net::EventLoopThreadPool::EventLoopThreadPool(EventLoop* loop,
                                                      bool is_epoll,
                                                      int n,
                                                      std::string name) :
    threads_num_(n),
    name_(std::move(name)), base_loop_(loop), is_epoll_(is_epoll) {
	// threads_.push_back()
}

netlib::net::EventLoopThreadPool::~EventLoopThreadPool() {
	if (is_started_) {
		is_started_ = false;
		for (EventLoopThread* thread : threads_) {
			delete thread;
		}
	}
	// base_loop_->quit();
}

netlib::net::EventLoop* netlib::net::EventLoopThreadPool::GetNextLoop() {
	assert(is_started_);
	base_loop_->AssertInLoopThread();
	if (loops_.empty()) {
		return base_loop_;
	}
	if (ImplicitCast<size_t>(next_loop_) == loops_.size()) {
		next_loop_ = 0;
	}
	return loops_.at(next_loop_++);
}

void netlib::net::EventLoopThreadPool::Start(const ThreadInitCallBack& cb) {
	assert(!is_started_);
	base_loop_->AssertInLoopThread();
	assert(threads_num_ >= 0);
	is_started_ = true;
	char index = '1';
	for (int i = 0; i < threads_num_; ++i) {
		// threads_.emplace_back(cb, name_ + index++);
		// EventLoopThread thread(cb, name_ + index++);
		threads_.push_back(new EventLoopThread(is_epoll_, cb, name_ + index++));
		loops_.push_back(threads_.back()->StartLoop());
	}
	if (threads_num_ == 0 && cb) {
		cb(base_loop_);
	}
}
